<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>

  <script>
    /*
      数组常用方法3
        + forEach()
        + 专门用来遍历数组的方法

      语法:
        => 数组.forEach(function (item, index, arr) {
          item 表示数组的每一项
          index 表示数组每一项的索引
          arr 表示原始数组
        })
      返回值:
        => 没有, undefined
      意义: 用来遍历数组
    */

    // var arr = [ 100, 200, 300, 400, 500, 600 ]
    // var arr2 = [ 10, 20, 30, 40 ]

    // a 会根据数组内有多少数据, 执行多少回
    // arr.forEach(function a(item, index, arr) {
    //   console.log('我执行了', item, index, arr)
    //   // 可以直接书写每一次循环你要做的事情
    // })



    // 我自己模仿一个 forEach 方法
    // function myForEach(cb) {
    //   // 需要在这里直到是谁调用了我
    //   // 我就去遍历谁
    //   // console.log('我被谁调用了呢 ? ', this)

    //   // 只需要遍历 this
    //   for (var i = 0; i < this.length; i++) {
    //     // 在循环内, this[i] 是当前这个数组的每一项
    //     // 在循环内, i 是当前这个数组每一项的索引
    //     // 在循环内, this 就是当前这个数组
    //     cb(this[i], i, this)
    //   }
    // }

    // 1. 能不能像 forEach 一样直接被 数组.myForEach 调用
    // 需要让我封装的方法能被数组直接调用
    // 需要把这个方法赋值给一个 "空间" 内
    // 把我们自己写的 myForEach 放在 "数组方法空间" 内
    // "数组方法空间" 是一个对象数据类型
    // "数组方法空间" 被我们叫做 Array.prototype
    // Array.prototype.myForEach = myForEach
    // var arr = [ 10, 20 ]
    // arr.myForEach()

    // arr.myForEach(function (item, index, arr) { console.log('我是 arr 调用', item, index, arr) })
    // arr2.myForEach()

    // 求 arr 数组内每一项的和
    // 在循环内做的事情: 把每一项叠加在一个初始变量身上
    // var sum = 0
    // arr.myForEach(function (item) {
    //   sum += item
    // })
    // console.log(sum)


    // 2. forEach 是用来遍历数组的
    // 在 myForEach 内也需要可以遍历数组
    // 遍历的不是我随便定义的数组, 而是哪一个数组调用我, 我遍历谁
    // a1.forEach()   在 forEach 内遍历 a1 数组
    // a2.forEach()   在 forEach 内遍历 a2 数组
    // a2.myForEach()   在 myForEach 内遍历 a2 数组
    // 在我封装的方法内直到, 是哪一个数组在调用我
    // 在函数内有一个关键字, 叫做 this
    //   今天: 哪一个数组调用这个方法, 方法内的 this 就是谁


    // 例子: 现在有一个对象叫做 obj
    // var obj = {}
    // var name = 'Jack'
    // console.log(obj)
    // // 需要把 myForEach 放在 obj 内
    // obj.myForEach = myForEach
    // // 需要把一个 name 放在对象内
    // obj.name = name
    // console.log(obj)






    // 1. 需要封装一个方法, 让数组可以直接调用
    var arr = [ 100, 200, 300, 400 ]
    // 需要把这个方法放在 Array.prototype 这个对象内
    Array.prototype.myForEach = myForEach
    function myForEach(cb) {
      // 2. 在我们封装好的函数内, this 就是调用我的那个数组
      // 遍历 this
      for (var i = 0; i < this.length; i++) {
        // 循环遍历多少遍, 就把锦囊执行多少遍
        // 在调用锦囊的时候, 把 数组的每一项 索引 原始数组 给到锦囊内部
        cb(this[i], i, this)
      }
    }

    arr.myForEach(function (item, index, arr) {
      console.log('锦囊妙计', item, index, arr)
    })



  </script>
</body>
</html>
